package net.jcip.examples.chapter7;

import java.util.*;
import java.util.concurrent.*;

/**
 * TrackingExecutor
 * <p/>
 * ExecutorService that keeps track of cancelled tasks after shutdown
 *
 * @author Brian Goetz and Tim Peierls
 */

/**
 * isShutdown和isTerminated是Java并发包（java.util.concurrent）中ExecutorService接口的一部分，用于检查线程池的状态。两者有不同的含义和用途：
 *
 * isShutdown
 * 含义: isShutdown方法返回一个布尔值，表示线程池是否已经被关闭。
 * 何时返回true: 当调用了shutdown()或shutdownNow()方法后，isShutdown会返回true。
 * 状态: isShutdown返回true时，线程池不再接受新任务，但仍然会继续执行已提交的任务（对于shutdown()方法）或尝试停止正在执行的任务（对于shutdownNow()方法）。
 *
 *
 * isTerminated
 * 含义: isTerminated方法返回一个布尔值，表示线程池是否已完全终止。
 * 何时返回true: 当所有任务，包括在关闭时正在执行的任务和在队列中的任务都已完成时，isTerminated会返回true。
 * 状态: isTerminated返回true时，线程池中的所有任务都已执行完毕，线程池已完全停止，不再执行任何任务。
 * 区别总结
 * 触发条件不同:
 *
 * isShutdown: 当shutdown()或shutdownNow()被调用时就会返回true。
 * isTerminated: 只有当所有已提交的任务完成执行之后才会返回true。
 * 线程池状态:
 *
 * isShutdown: 表示线程池不再接受新任务，但可能仍在处理已提交的任务。
 * isTerminated: 表示线程池中的所有任务都已完成，线程池已完全停止。
 */
public class TrackingExecutor extends AbstractExecutorService {
    private final ExecutorService exec;
    private final Set<Runnable> tasksCancelledAtShutdown = Collections.synchronizedSet(new HashSet<>());

    public TrackingExecutor(ExecutorService exec) {
        this.exec = exec;
    }

    /**
     * 启动有序关闭，其中先前提交的任务将被执行，但不会接受任何新任务。
     */
    public void shutdown() {
        exec.shutdown();
    }

    /**
     * 尝试停止所有正在执行的任务，停止等待任务的处理，并返回等待执行的任务列表。
     * @return
     */
    public List<Runnable> shutdownNow() {
        return exec.shutdownNow();
    }

    public boolean isShutdown() {
        //含义: isShutdown方法返回一个布尔值，表示线程池是否已经被关闭。
        //何时返回true: 当调用了shutdown()或shutdownNow()方法后，isShutdown会返回true。
        return exec.isShutdown();
    }

    public boolean isTerminated() {
        //含义: isTerminated方法返回一个布尔值，表示线程池是否已完全终止。
        //何时返回true: 当所有任务，包括在关闭时正在执行的任务和在队列中的任务都已完成时，isTerminated会返回true。
        return exec.isTerminated();
    }

    public boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException {
        return exec.awaitTermination(timeout, unit);
    }

    public List<Runnable> getCancelledTasks() {
        if (!exec.isTerminated())
            throw new IllegalStateException(/*...*/);
        return new ArrayList<Runnable>(tasksCancelledAtShutdown);
    }

    public void execute(final Runnable runnable) {
        exec.execute(() -> {
            try {
                runnable.run();
            } finally {
                if (isShutdown() && Thread.currentThread().isInterrupted())
                    tasksCancelledAtShutdown.add(runnable);
            }
        });
    }

    public static void main(String[] args){
        int N_CPUS = Runtime.getRuntime().availableProcessors();
        System.out.println(N_CPUS);
    }


}
